package com.cqndt.disaster.device.controller;

import java.util.Map;
import java.util.HashMap;
import java.io.IOException;
import javax.imageio.ImageIO;
import java.security.KeyPair;
import java.awt.image.BufferedImage;
import com.google.code.kaptcha.Producer;
import org.apache.shiro.subject.Subject;
import javax.servlet.ServletOutputStream;
import com.google.code.kaptcha.Constants;
import java.security.interfaces.RSAPublicKey;
import com.cqndt.disaster.device.util.Result;
import javax.servlet.http.HttpServletRequest;
import java.security.interfaces.RSAPrivateKey;
import com.cqndt.disaster.device.vo.TabUserVo;
import javax.servlet.http.HttpServletResponse;
import com.cqndt.disaster.device.util.Constant;
import com.cqndt.disaster.device.util.RASUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.AuthenticationException;
import com.cqndt.disaster.device.domain.TabMapservice;
import com.cqndt.disaster.device.service.TabMapService;
import com.cqndt.disaster.device.common.shrio.ShiroUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/login")
public class TabUserController {

	@Autowired
	private Producer producer;
	@Autowired
	private TabMapService tabMapService;

	@GetMapping(value="getCaptcha")
	public void captcha(HttpServletRequest req, HttpServletResponse response) throws IOException {
		response.setHeader("Cache-Control", "no-store, no-cache");
		response.setContentType("image/jpeg");
		// 生成文字验证码
		String text = producer.createText();
		// 生成图片验证码
		BufferedImage image = producer.createImage(text);
		// 保存到session
		req.getSession(true).setAttribute("captcha", text);
		ServletOutputStream out = response.getOutputStream();
		ImageIO.write(image, "jpg", out);
	}

	/**
	 * @param userName
	 * @param password
	 * @param request
	 * @return 登录
	 **/
	@PostMapping(value="login")
	public Result login(String userName, String password) {
		Result result = new Result();
		try {
			// 将前端密码解密
			Object privateKey = ShiroUtils.getSession().getAttribute(Constant.PRIVATE_KEY);
			if (null == privateKey) {
				return new Result().failure(404, "请刷新后重新登陆");
			}
			byte[] passwords = RASUtils.decrypt((RSAPrivateKey) privateKey, RASUtils.hexStringToBytes(password));
			// 还原密码
			password = new String(passwords).trim();
			Subject subject = ShiroUtils.getSubject();
			UsernamePasswordToken token = new UsernamePasswordToken(userName, password);
			subject.login(token);

			Map<String, Object> map = new HashMap<>();
			TabUserVo userVo = ShiroUtils.getUserEntity();
			if ((userVo.getAduitType() & 2) == 0) {
				return new Result().failure(404, "该用户没有访问权限");
			}
			map.put("userVo", userVo);
			TabMapservice tabMap = tabMapService.getByUserId(userVo.getId());
			map.put("tabMap", tabMap);
			result.setData(map);
			// session验证码和秘钥移除
			ShiroUtils.getSession().removeAttribute(Constants.KAPTCHA_SESSION_KEY);
			ShiroUtils.getSession().removeAttribute(Constant.PRIVATE_KEY);
		} catch (UnknownAccountException e) {
			return result.failure(-1, e.getMessage());
		} catch (IncorrectCredentialsException e) {
			return result.failure(-1, "账号或密码不正确");
		} catch (LockedAccountException e) {
			return result.failure(-1, "账号已被禁用,请联系管理员");
		} catch (AuthenticationException e) {
			return result.failure(-1, "账户验证失败");
		} catch (Exception e) {
			return result.failure(-1, e.getMessage());
		}
		return result;
	}

	/**
	 * @param code
	 * @return 验证码
	 **/
	@GetMapping(value="checkCaptcha")
	public Map<String, Object> checkCaptcha(HttpServletRequest req, String code) {
		Map<String, Object> data = new HashMap<String, Object>();
		try {
			Object obj = req.getSession(true).getAttribute("captcha");
			if (obj == null) {
				data.put("code", -1);
				data.put("msg", "验证错误");
				return data;
			}
			String kaptcha = obj.toString();
			if (!kaptcha.equalsIgnoreCase(code)) {
				data.put("code", -1);
				data.put("msg", "验证码错误");
				return data;
			}
		} catch (Exception e) {
			data.put("code", -1);
			data.put("msg", e.getMessage());
			return data;
		}
		data.put("code", 0);
		return data;
	}

	/**
	 * @param request
	 * @return 获取公钥和私钥
	 **/
	@GetMapping(value = "getKey")
	public Result getKey(HttpServletRequest request) {
		HashMap<Object, Object> hashMap = new HashMap<>();
	    RSAPublicKey rsapPublicKey = null;
	    RSAPrivateKey rsaPrivateKey = null;
	    try {
	        KeyPair publicKey = RASUtils.generateKeyPair();
	        rsapPublicKey = (RSAPublicKey) publicKey.getPublic();
	        rsaPrivateKey = (RSAPrivateKey) publicKey.getPrivate();
	    } catch (Exception e) {
	        e.printStackTrace();
	    }
	    //保存到shiro session
	    ShiroUtils.setSessionAttribute(Constant.PRIVATE_KEY, rsaPrivateKey);
	    hashMap.put("publicKey", rsapPublicKey.getModulus().toString(16));
	    return new Result().success(hashMap);
    }

	/**
	 * @return 退出
	 **/
	@GetMapping("logout")
	public Result logout(HttpServletRequest request) {
		ShiroUtils.logout();
        return new Result().success();
	}
}